package com.gerfmarquez.nymph.music.core;

import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;

import android.content.Context;
import android.util.Log;

import com.gerfmarquez.nymph.TestNotesDurationActivity;

public class MusicCore {
	
	private static int bpm;
	public static void setBpm(int bpm) {
		MusicCore.bpm = bpm;
	}

	private final static int HALF_SEC_WAV_BYTES = 22050;
	private final static int FILE_WAV_BYTES = 88200;


    public static byte []A;
    public static byte []As;
    public static byte []B;
    public static byte []C;
    public static byte []Cs;
    public static byte []D;
    public static byte []Ds;
    public static byte []E;
    public static byte []F;
    public static byte []Fs;
    public static byte []G;
    public static byte []Gs;
    
    byte[][] notesToPlay;
    
    static final String TAG= "MusicCore";
    
	
	private static void closeStream(InputStream is) {
    	try {
    		if (is != null)
    			is.close();
    	} catch(IOException io) {
    	}
	}
	public static void init(TestNotesDurationActivity tnda) {
		final Context appContext = tnda.getApplicationContext();
		new  Thread() {
			public void run() {
				A = getbytes(appContext,  "A");
				As = getbytes(appContext, "As");
				B = getbytes(appContext,  "B");
				C = getbytes(appContext,  "C");
				Cs = getbytes(appContext, "Cs");
				D = getbytes(appContext,  "D");
				Ds = getbytes(appContext, "Ds");
				E = getbytes(appContext,  "E");
				F = getbytes(appContext,  "F");
				Fs = getbytes(appContext, "Fs");
				G = getbytes(appContext,  "G");
				Gs = getbytes(appContext, "Gs");
			}
		}.start();
        
	}
	private static byte[] getbytes(Context context, String filename) {
		 InputStream stream = null;
	    	BufferedInputStream bis = null;
	    	DataInputStream dis = null;
	    	
	    	byte[] fileBytes = null;
	    	
	        try {
	        	
	        	stream = context.getAssets().open(filename);
	        	Log.d(TAG, "File found: "+filename );
	        	bis = new BufferedInputStream(stream);
	        	dis = new DataInputStream(bis);
	        	
	        	Log.d(TAG, "Total number of bytes in "+filename);// + stream.available());
	        	int bytes = 1;
	        	bytes = FILE_WAV_BYTES;
	        	fileBytes = new byte[bytes];
	        	int i=0;
	        	for(; i < bytes; i++) {
	        		fileBytes[i] = dis.readByte();
	        	}
	        	Log.d(TAG, ""+(i)+" bytes read for file: " + filename);
//	        	dis.read(fileBytes);
	        	
	        } catch(IOException io) {
	        	Log.d(TAG, "File could not be opened", io);
	        	fileBytes = null;
	        }
	        finally {
	        	closeStream(stream);
	        	closeStream(bis);
	        	closeStream(dis);
	        }
	        return fileBytes;
	}
    
    static int cutLength(int noteRhythm) {
    	int length = 0;
    	int normalBPM = 120;
    	int bytesPerBPM = (HALF_SEC_WAV_BYTES*normalBPM)/bpm;
    	int module;
    	switch(noteRhythm) {
    	case 1:
    		length = bytesPerBPM*4;
    		break;
    	case 2:
    		length = bytesPerBPM*2;
    		break;
    	case 3:
    		length = (int)(bytesPerBPM/3);
    		break;
    	case 4:
    		length = bytesPerBPM;
    		break;
    	case 8:
    		length = (bytesPerBPM/2);
    		break;
    	}
    	module = length%2;
//    	if(module == 1) {
//    		length += 1; // solucion temporal porque afecta al metodo de abajo append ya que le aumenta los bytes para leer pero no hay de donde leer
//    	}
    	Log.d(TAG, "Length of note rhythm: "+noteRhythm+" is : "+ length);
    	Log.d(TAG, "Module of bytes: "+module);
    	return length;
    }
    
    public static byte[] append(byte[] mainArray, byte[] toAppend, int currentIndex, int bytesToWrite) {
    	loopAppend:
    	for(int j = 0, i = currentIndex; i<currentIndex+bytesToWrite; i++,j++) {
    		try {
    			if(j < toAppend.length)
    				mainArray[i] = toAppend[j];
    			else
    				mainArray[i] = 127;//@todo poner silencio
    		}
    		catch(ArrayIndexOutOfBoundsException aiobe) {
    			Log.e(TAG, "Variable i = " + i+ " variable j = " +j + " variable bytes to Write = " +bytesToWrite, aiobe);
    			Log.e(TAG, "Array length mainArray  = " + mainArray.length+ " toAppendLength = " +toAppend + " currentIndex = " +currentIndex);
    			break loopAppend;
    		}
    	}
    	return mainArray;
    }
}
